//imr
import React, { useState, useMemo, useEffect, memo, useCallback } from 'react';
import classnames from 'classnames';
import PropTypes from 'prop-types';
import './CitySelector.css';

//
const CityItem = memo(function CityItem(props) {
  const { name, onSelect } = props;
  return (
    <li className="city-li" onClick={() => onSelect(name)}>
      {name}
    </li>
  );
});
CityItem.propTypes = {
  name: PropTypes.string.isRequired,
  onSelect: PropTypes.func.isRequired,
};

const CitySection = memo(function CitySection(props) {
  const { title, cities = [], onSelect } = props;

  return (
    <ul className="city-ul" data-cate={title}>
      <li className="city-li" key="title">
        {title}
      </li>
      {cities.map((city) => {
        return (
          <CityItem key={city.name} name={city.name} onSelect={onSelect} />
        );
      })}
    </ul>
  );
});
CitySection.propTypes = {
  cities: PropTypes.array,
  title: PropTypes.string.isRequired,
  onSelect: PropTypes.func.isRequired,
};

const CityList = memo(function CityList(props) {
  const { sections = [], onSelect, toAlpha } = props;
  return (
    <div className="city-list">
      <div className="city-cate">
        {sections.map((section) => {
          return (
            <CitySection
              cities={section.citys}
              key={section.title}
              title={section.title}
              onSelect={onSelect}
            />
          );
        })}
      </div>
      <div className="city-index">
        {alphabet.map((alpha) => {
          return <AlphaIndex key={alpha} alpha={alpha} onClick={toAlpha} />;
        })}
      </div>
    </div>
  );
});

CityList.propTypes = {
  sections: PropTypes.array.isRequired,
  onSelect: PropTypes.func.isRequired,
};

const SuggestItem = memo(function SuggestItem(props) {
  const { name, onClick } = props;
  return (
    <li className="city-suggest-li" onClick={() => onClick(name)}>
      {name}
    </li>
  );
});
SuggestItem.propTypes = {
  name: PropTypes.string.isRequired,
  onClick: PropTypes.func.isRequired,
};

const Suggest = memo(function Suggest(props) {
  const { searchKey, onSelect } = props;
  //存储返回的数据
  const [result, setResult] = useState([]);

  useEffect(() => {
    fetch('/rest/search?key=' + encodeURIComponent(searchKey))
      //将字符串转化为一个json对象
      .then((res) => res.json())
      .then((data) => {
        const { result, searchKey: sKey } = data;
        if (sKey === searchKey) {
          setResult(result);
        }
      })
      .catch((err) => {});
  }, [searchKey]);
  // const fallBackResult = result.length ? result : [{ display: searchKey }]

  const fallBackResult = useMemo(() => {
    return result.length ? result : [{ display: searchKey }];
  }, [result, searchKey]);
  return (
    <div className="city-suggest">
      <ul className="city-suggest-ul">
        {fallBackResult.map((item) => {
          return (
            <SuggestItem
              key={item.display}
              name={item.display}
              onClick={onSelect}
            />
          );
        })}
      </ul>
    </div>
  );
});

Suggest.propTypes = {
  searchKey: PropTypes.string.isRequired,
  onSelect: PropTypes.func.isRequired,
};

const AlphaIndex = memo(function AlphaIndex(props) {
  const { alpha, onClick } = props;

  return (
    <i
      className="city-index-item"
      onClick={() => {
        onClick(alpha);
      }}
    >
      {alpha}
    </i>
  );
});
//创建26个英文字符的数组
// const alphabet = Array.from(new Array(26), (ele, index) =>
//   String.fromCharCode(65 + index)
// )

const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');

AlphaIndex.propType = {
  alpha: PropTypes.string.isRequired,
  onClick: PropTypes.func.isRequired,
};

//edf
const CitySelector = memo(function CitySelector(props) {
  const { show, isLoading, cityData, onBack, fetchCityData, onSelect } = props;
  // console.log(cityData)

  const [searchKey, setSearchKey] = useState('');
  //有性能问题
  // const key = searchKey.trim()
  //优化后:是根据searchKey的变化去更新 searchKey依赖的数据
  const key = useMemo(() => {
    return searchKey.trim();
  }, [searchKey]);

  useEffect(() => {
    //没有城市浮层  正在获取城市浮层  已经拥有城市数据  这三种情况不需要重新获取城市数据
    if (!show || isLoading || cityData) return;
    fetchCityData();
  }, [cityData, fetchCityData, isLoading, show]);
  //跳转至字符title函数
  const toAlpha = useCallback((alpha) => {
    document.querySelector(`[data-cate=${alpha}]`).scrollIntoView();
  }, []);

  //定义浮层列表函数
  const outputCitySections = () => {
    // debugger
    if (isLoading) {
      return <div>Loading</div>;
    }
    if (cityData && cityData.cityList) {
      return (
        <CityList
          onSelect={onSelect}
          sections={cityData.cityList}
          toAlpha={toAlpha}
        />
      );
    }

    return <div>No data !</div>;
  };

  return (
    // <div className={['city-selector', show ? '' : 'hidden'].filter(Boolean).join(' ')}></div>
    <div className={classnames('city-selector', { hidden: !show })}>
      <div className="city-search">
        <div className="search-back" onClick={() => onBack()}>
          <svg width="42" height="42">
            <polyline
              points="25,13 16,21 25,29"
              stroke="#fff"
              strokeWidth="2"
              fill="none"
            />
          </svg>
        </div>

        <div className="search-input-wrapper">
          <input
            type="text"
            value={searchKey}
            placeholder="城市.车站的中文或拼音"
            className="search-input"
            onChange={(e) => setSearchKey(e.target.value)}
          />
          <i
            className={classnames('search-clean', {
              hidden: key.length === 0,
            })}
            onClick={() => setSearchKey('')}
          >
            &#xf063;
          </i>
        </div>
      </div>
      {Boolean(key) && <Suggest searchKey={key} onSelect={onSelect} />}
      {outputCitySections()}
    </div>
  );
});
/**
 * 父组件传入属性值的校验
 */
CitySelector.propTypes = {
  show: PropTypes.bool.isRequired,
  isLoading: PropTypes.bool.isRequired,
  cityData: PropTypes.object,
  onBack: PropTypes.func.isRequired,
  fetchCityData: PropTypes.func.isRequired,
};

export default CitySelector;
